{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# IMDB"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%reload_ext autoreload\n",
    "%autoreload 2\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from fastai import *\n",
    "from fastai.text import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "torch.cuda.set_device(2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Preparing the data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First let's download the dataset we are going to study. The [dataset](http://ai.stanford.edu/~amaas/data/sentiment/) has been curated by Andrew Maas et al. and contains a total of 100,000 reviews on IMDB. 25,000 of them are labelled as positive and negative for training, another 25,000 are labelled for testing (in both cases they are highly polarized). The remaning 50,000 is an additional unlabelled data (but we will find a use for it nonetheless).\n",
    "\n",
    "We'll begin with a sample we've prepared for you, so that things run quickly before going over the full dataset."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[PosixPath('/home/jhoward/.fastai/data/imdb_sample/texts.csv'),\n",
       " PosixPath('/home/jhoward/.fastai/data/imdb_sample/models'),\n",
       " PosixPath('/home/jhoward/.fastai/data/imdb_sample/export.pkl'),\n",
       " PosixPath('/home/jhoward/.fastai/data/imdb_sample/tmp')]"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "path = untar_data(URLs.IMDB_SAMPLE)\n",
    "path.ls()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It only contains one csv file, let's have a look at it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>label</th>\n",
       "      <th>text</th>\n",
       "      <th>is_valid</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>negative</td>\n",
       "      <td>Un-bleeping-believable! Meg Ryan doesn't even ...</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>positive</td>\n",
       "      <td>This is a extremely well-made film. The acting...</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>negative</td>\n",
       "      <td>Every once in a long while a movie will come a...</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>positive</td>\n",
       "      <td>Name just says it all. I watched this movie wi...</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>negative</td>\n",
       "      <td>This movie succeeds at being one of the most u...</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      label                                               text  is_valid\n",
       "0  negative  Un-bleeping-believable! Meg Ryan doesn't even ...     False\n",
       "1  positive  This is a extremely well-made film. The acting...     False\n",
       "2  negative  Every once in a long while a movie will come a...     False\n",
       "3  positive  Name just says it all. I watched this movie wi...     False\n",
       "4  negative  This movie succeeds at being one of the most u...     False"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.read_csv(path/'texts.csv')\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'This is a extremely well-made film. The acting, script and camera-work are all first-rate. The music is good, too, though it is mostly early in the film, when things are still relatively cheery. There are no really superstars in the cast, though several faces will be familiar. The entire cast does an excellent job with the script.<br /><br />But it is hard to watch, because there is no good end to a situation like the one presented. It is now fashionable to blame the British for setting Hindus and Muslims against each other, and then cruelly separating them into two countries. There is some merit in this view, but it\\'s also true that no one forced Hindus and Muslims in the region to mistreat each other as they did around the time of partition. It seems more likely that the British simply saw the tensions between the religions and were clever enough to exploit them to their own ends.<br /><br />The result is that there is much cruelty and inhumanity in the situation and this is very unpleasant to remember and to see on the screen. But it is never painted as a black-and-white case. There is baseness and nobility on both sides, and also the hope for change in the younger generation.<br /><br />There is redemption of a sort, in the end, when Puro has to make a hard choice between a man who has ruined her life, but also truly loved her, and her family which has disowned her, then later come looking for her. But by that point, she has no option that is without great pain for her.<br /><br />This film carries the message that both Muslims and Hindus have their grave faults, and also that both can be dignified and caring people. The reality of partition makes that realisation all the more wrenching, since there can never be real reconciliation across the India/Pakistan border. In that sense, it is similar to \"Mr & Mrs Iyer\".<br /><br />In the end, we were glad to have seen the film, even though the resolution was heartbreaking. If the UK and US could deal with their own histories of racism with this kind of frankness, they would certainly be better off.'"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df['text'][1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It contains one line per review, with the label ('negative' or 'positive'), the text and a flag to determine if it should be part of the validation set or the training set. If we ignore this flag, we can create a DataBunch containing this data in one line of code:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "data_lm = TextDataBunch.from_csv(path, 'texts.csv')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "By executing this line a process was launched that took a bit of time. Let's dig a bit into it. Images could be fed (almost) directly into a model because they're just a big array of pixel values that are floats between 0 and 1. A text is composed of words, and we can't apply mathematical functions to them directly. We first have to convert them to numbers. This is done in two differents steps: tokenization and numericalization. A `TextDataBunch` does all of that behind the scenes for you.\n",
    "\n",
    "Before we delve into the explanations, let's take the time to save the things that were calculated."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "data_lm.save()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next time we launch this notebook, we can skip the cell above that took a bit of time (and that will take a lot more when you get to the full dataset) and load those results like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "data = TextDataBunch.load(path)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Tokenization"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The first step of processing we make texts go through is to split the raw sentences into words, or more exactly tokens. The easiest way to do this would be to split the string on spaces, but we can be smarter:\n",
    "\n",
    "- we need to take care of punctuation\n",
    "- some words are contractions of two different words, like isn't or don't\n",
    "- we may need to clean some parts of our texts, if there's HTML code for instance\n",
    "\n",
    "To see what the tokenizer had done behind the scenes, let's have a look at a few texts in a batch."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table>  <col width='90%'>  <col width='10%'>  <tr>\n",
       "    <th>text</th>\n",
       "    <th>target</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>xxbos xxfld 1 xxmaj raising xxmaj victor xxmaj vargas : a xxmaj review \\n\\n xxmaj you know , xxmaj raising xxmaj victor xxmaj vargas is like sticking your hands into a big , xxunk bowl of xxunk . xxmaj it 's warm and gooey , but you 're not sure if it feels right . xxmaj try as i might , no matter how warm and gooey xxmaj raising xxmaj</th>\n",
       "    <th>negative</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>xxbos xxfld 1 xxup the xxup shop xxup around xxup the xxup corner is one of the xxunk and most feel - good romantic comedies ever made . xxmaj there 's just no getting around that , and it 's hard to actually put one 's feeling for this film into words . xxmaj it 's not one of those films that tries too hard , nor does it come</th>\n",
       "    <th>positive</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>xxbos xxfld 1 xxmaj now that xxmaj che(2008 ) has finished its relatively short xxmaj australian cinema run ( extremely limited xxunk screen in xxmaj xxunk , after xxunk ) , i can xxunk join both xxunk of \" xxmaj at xxmaj the xxmaj movies \" in taking xxmaj steven xxmaj soderbergh to xxunk . \\n\\n xxmaj it 's usually satisfying to watch a film director change his style /</th>\n",
       "    <th>negative</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>xxbos xxfld 1 xxmaj this film sat on my xxmaj xxunk for weeks before i watched it . i xxunk a self - indulgent xxunk flick about relationships gone bad . i was wrong ; this was an xxunk xxunk into the screwed - up xxunk of xxmaj new xxmaj xxunk . \\n\\n xxmaj the format is the same as xxmaj max xxmaj xxunk ' \" xxmaj la xxmaj xxunk</th>\n",
       "    <th>positive</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>xxbos xxfld 1 xxmaj many xxunk that this is n't just a classic due to the fact that it 's the first xxup 3d game , or even the first xxunk - up . xxmaj it 's also one of the first xxunk games , one of the xxunk definitely the first ) truly claustrophobic games , and just a pretty well - xxunk gaming experience in general . xxmaj</th>\n",
       "    <th>positive</th>\n",
       "  </tr>\n",
       "</table>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "data = TextClasDataBunch.load(path)\n",
    "data.show_batch()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The texts are truncated at 100 tokens for more readability. We can see that it did more than just split on space and punctuation symbols: \n",
    "- the \"'s\" are grouped together in one token\n",
    "- the contractions are separated like his: \"did\", \"n't\"\n",
    "- content has been cleaned for any HTML symbol and lower cased\n",
    "- there are several special tokens (all those that begin by xx), to replace unkown tokens (see below) or to introduce different text fields (here we only have one)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Numericalization"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Once we have extracted tokens from our texts, we convert to integers by creating a list of all the words used. We only keep the ones that appear at list twice with a maximum vocabulary size of 60,000 (by default) and replace the ones that don't make the cut by the unknown token `UNK`.\n",
    "\n",
    "The correspondance from ids tokens is stored in the `vocab` attribute of our datasets, in a dictionary called `itos` (for int to string)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['xxunk', 'xxpad', 'xxmaj', 'the', ',', '.', 'and', 'a', 'of', 'to']"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.vocab.itos[:10]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And if we look at what a what's in our datasets, we'll see the tokenized text as a representation:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text xxbos xxfld 1 i watched this movie with some friends a couple months ago , i still laugh today thinking about some of the utter stupidity . xxmaj the first few scenes alone were hilarious . i wo n't spoil anything for those who wish to see it , i would n't want to ruin the laughs . xxmaj needless to say the entire time i watched this movie i was trying to figure out exactly what the point of anything the characters in this movie were doing . xxmaj towards the end we all got bored however , as the initial hilarity and shock of a movie being this random wore off . xxmaj there is no plot and not a trace of decent acting . xxmaj the characters are about as well developed as those in a xxunk \" xxmaj learn to xxmaj read \" book . xxmaj they even managed to make a lesbian sex scene uninteresting ."
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.train_ds[0][0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "But the underlying data is all numbers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 44,  45,  41,  13, 317,  15,  24,  25,  60, 330])"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.train_ds[0][0].data[:10]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### With the data block API"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can use the data block API with NLP and have a lot more flexibility than what the default factory methods offer. In the previous example for instance, the data was randomly split between train and validation instead of reading the third column of the csv.\n",
    "\n",
    "With the data block API though, we have to manually call the tokenize and numericalize steps. This allows more flexibility, and if you're not using the defaults from fastai, the variaous arguments to pass will appear in the step they're revelant, so it'll be more readable."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "data = (TextList.from_csv(path, 'texts.csv', cols='text')\n",
    "                .split_from_df(col=2)\n",
    "                .label_from_df(cols=0)\n",
    "                .databunch())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Language model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that language models can use a lot of GPU, so you may need to decrease batchsize here."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "bs=48"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now let's grab the full dataset for what follows."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[PosixPath('/home/jhoward/.fastai/data/imdb/imdb.vocab'),\n",
       " PosixPath('/home/jhoward/.fastai/data/imdb/models'),\n",
       " PosixPath('/home/jhoward/.fastai/data/imdb/tmp_lm'),\n",
       " PosixPath('/home/jhoward/.fastai/data/imdb/train'),\n",
       " PosixPath('/home/jhoward/.fastai/data/imdb/test'),\n",
       " PosixPath('/home/jhoward/.fastai/data/imdb/README'),\n",
       " PosixPath('/home/jhoward/.fastai/data/imdb/tmp_clas')]"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "path = untar_data(URLs.IMDB)\n",
    "path.ls()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[PosixPath('/home/jhoward/.fastai/data/imdb/train/pos'),\n",
       " PosixPath('/home/jhoward/.fastai/data/imdb/train/unsup'),\n",
       " PosixPath('/home/jhoward/.fastai/data/imdb/train/unsupBow.feat'),\n",
       " PosixPath('/home/jhoward/.fastai/data/imdb/train/labeledBow.feat'),\n",
       " PosixPath('/home/jhoward/.fastai/data/imdb/train/neg')]"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(path/'train').ls()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The reviews are in a training and test set following an imagenet structure. The only difference is that there is an `unsup` folder in `train` that contains the unlabelled data.\n",
    "\n",
    "We're not going to train a model that classifies the reviews from scratch. Like in computer vision, we'll use a model pretrained on a bigger dataset (a cleaned subset of wikipeia called [wikitext-103](https://einstein.ai/research/blog/the-wikitext-long-term-dependency-language-modeling-dataset)). That model has been trained to guess what the next word, its input being all the previous words. It has a recurrent structure and a hidden state that is updated each time it sees a new word. This hidden state thus contains information about the sentence up to that point.\n",
    "\n",
    "We are going to use that 'knowledge' of the English language to build our classifier, but first, like for computer vision, we need to fine-tune the pretrained model to our particular dataset. Because the English of the reviex lefts by people on IMDB isn't the same as the English of wikipedia, we'll need to adjust a little bit the parameters of our model. Plus there might be some words extremely common in that dataset that were barely present in wikipedia, and therefore might no be part of the vocabulary the model was trained on."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This is where the unlabelled data is going to be useful to us, as we can use it to fine-tune our model. Let's create our data object with the data block API (next line takes a few minutes)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "data_lm = (TextList.from_folder(path)\n",
    "           #Inputs: all the text files in path\n",
    "            .filter_by_folder(include=['train', 'test']) \n",
    "           #We may have other temp folders that contain text files so we only keep what's in train and test\n",
    "            .random_split_by_pct(0.1)\n",
    "           #We randomly split and keep 10% (10,000 reviews) for validation\n",
    "            .label_for_lm()           \n",
    "           #We want to do a language model so we label accordingly\n",
    "            .databunch(bs=bs))\n",
    "data_lm.save('tmp_lm')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We have to use a special kind of `TextDataBunch` for the language model, that ignores the labels (that's why we put 0 everywhere), will shuffle the texts at each epoch before concatenating them all together (only for training, we don't shuffle for the validation set) and will send batches that read that text in order with targets that are the next word in the sentence.\n",
    "\n",
    "The line before being a bit long, we want to load quickly the final ids by using the following cell."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "data_lm = TextLMDataBunch.load(path, 'tmp_lm', bs=bs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table>  <col width='5%'>  <col width='95%'>  <tr>\n",
       "    <th>idx</th>\n",
       "    <th>text</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>0</th>\n",
       "    <th>xxbos i saw the xxup mst3 k version of this film and it is a bad movie - but its not nearly as bad as its low xxup imdb rating ( currently 1.8 out of 10 ) . xxmaj at least the movie has a few production values and it apparently had a competent editor ( unlike the movies that truly are awful ) . xxmaj the primary problem with</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>1</th>\n",
       "    <th>xxmaj after the president of the xxmaj united xxmaj states accepts xxmaj jesus as his savior he immediately becomes a suicide bomber and blows up a skyscraper in the middle of the city . xxmaj osama xxmaj bin xxmaj laden will be very jealous when he sees this film ! xxbos i 'm not much of an expert on acting or other movie details , but this movie just hit</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>2</th>\n",
       "    <th>definitely an acquired taste and is possibly not suitable for the average fan of xxmaj hollywood blockbusters . xxbos xxmaj what makes xxup xxunk work as a bland , comfort film is what makes it not work as anything close to a good movie : namely , the paint - by - numbers script . xxmaj everything is rote , from the obligatory crew of friends ( xxmaj black ,</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>3</th>\n",
       "    <th>. xxmaj when xxmaj emerson finds out , and when xxmaj chuck wants to help with solving the murders , he does n't agree a bit -- for a while , we hear him call xxmaj chuck ' xxmaj dead girl ' . xxmaj this is all kept in secret from xxmaj olive , xxmaj chuck 's aunts xxmaj vivian and xxmaj lily ( xxmaj ellen xxmaj greene and xxmaj</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>4</th>\n",
       "    <th>i had already seen this a few years ago and have finally gotten the chance to review it . xxmaj but in my review , i was wondering if i should judge it on camp value ( like xxmaj plan 9 xxmaj from xxmaj outer xxmaj space ) or just on its own merits in terms of film - making style . i decided on the later , since this</th>\n",
       "  </tr>\n",
       "</table>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "data_lm.show_batch()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can then put this in a learner object very easily with a model loaded with the pretrained weights. They'll be downloaded the first time you'll execute the following line and stored in './fastai/models/' (or elsewhere if you specified different paths in your config file)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn = language_model_learner(data_lm, pretrained_model=URLs.WT103_1, drop_mult=0.3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.\n"
     ]
    }
   ],
   "source": [
    "learn.lr_find()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZgAAAEKCAYAAAAvlUMdAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4wLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvqOYd8AAAIABJREFUeJzt3Xd8leX9//HXJ5MsSAIBQgKEPWQJYYniwFrX123VWreltnW139afrd+Ob63WVm3Vaq3WUbWOfotaZwUciIiMhD0ChB1mIISEBDKv3x/noDFkHCD3OTnJ+/l4nIfn3OPcn8sT8s59X9e5bnPOISIi0tIiQl2AiIi0TQoYERHxhAJGREQ8oYARERFPKGBERMQTChgREfGEAkZERDyhgBEREU8oYERExBNRXr65mSUDzwDDAAfc6Jz7os76wcDzwGjgHufcQ3XWnQ08CkQCzzjnHmjueF26dHFZWVkt2gYRkbYsNzd3j3MuzYv39jRg8AXEB865y8wsBoivt74IuB24qO5CM4sEngC+ARQAC83sbefcqqYOlpWVRU5OTosVLyLS1pnZZq/e27NLZGbWEZgMPAvgnKt0zhXX3cY5t9s5txCoqrf7OCDfObfBOVcJvAZc6FWtIiLS8rzsg+kLFALPm9liM3vGzBIC3DcD2FrndYF/2RHMbKqZ5ZhZTmFh4fFVLCIiLcbLgInC17fypHPuRKAMuDvAfa2BZQ1O++yce9o5l+2cy05L8+QyooiIHAMvA6YAKHDOzfe/noYvcALdt2ed15nA9hasTUREPOZZwDjndgJbzWyQf9EUoMlO+joWAgPMrI9/cMCVwNselCkiIh7xehTZbcDL/pDYANxgZrcAOOf+ambdgRygI1BrZncCQ51zJWZ2KzAd3zDl55xzKz2uVUREWpCnAeOcWwJk11v81zrrd+K7/NXQvu8D73tXnYiIeEnf5A/A8oL9LNqyL9RliIiEFQVMM0oPVXHd8wu47tkFFJVVhrocEZGwoYBpxt9mb6CorJKyymoe+2hdqMsREQkbCpgm7C49xN8+28j5I9K5Ymwv/jFvMxv3lIW6LBGRsKCAacKfP8qnqqaWn5w1iB99YwAxURH84YO8UJclIhIWFDCN2LSnjFcXbOGqcb3I6pJA16QOTJ3cl/+s2Enu5qJQlyci0uopYBrx0Iw1xERFcNuU/l8umzq5L12TYrnvvdU41+DMNSIi4qeAacCygmLeXbaDm0/uQ9ekDl8uj4+J4sffGMiiLcV8sGJnCCsUEWn9FDANeHD6GlITYvju5L5HrLs8uycDuyXy4Iw1OosREWmCAqaeRVv28dm6Pdxyal+SOkQfsT4ywrj55L5sKCxjydbiBt5BRERAAXOEJz7OJzk+mqvH9250m7OHdyc2KoI3F28LYmUiIuFFAVPHqu0lfJS3m5sm9SEhtvFp2jp2iObMod14Z+l2qmpqg1ihiEj4UMDU8cSsfJJio7j2pKxmt714VAb7yquYvVZ30RQRaYgCxi9/9wHeX76Dayb2plPckX0v9U0emEZKfHSDl8lWbt/Pz95YTnlltRelioiEBQWM35Oz1hMbFcFNJ/cJaPuYqAjOH9GDmat2UXqo6svlBytruPWVxby6YAt/m73Rq3JFRFo9BQywtaicfy/ZxlXjetE5MTbg/S46MYOK6tqvfSfmoRlr2LinjCHpHXlq9np2lxzyomQRkVZPAQM8NXs9Eeb7pv7RGN0rmd6d4/n3Et9lsgUbi3ju841cM6E3T149mqqaWv44c60XJR/h8/w9vLVEo9pEpPXw+pbJrV7JoSpez93GZWN6kt4p7qj2NTMuGpXBYx+vY0PhAX46bSmZKXHcfc5gEmKjuGZCFn+fu5HrJ2UxuHvHo3rv6ppaIiMMM2tyuy17y7n3vVXMXLXL355qrpnQ+BBrEZFgafdnMB07RPPe7Sdze505x47GRSdm4Bxc/cx8Nu8t58HLRn45xPm2M/qTGBvF794/uhmYt+wtZ9LvP+Ybf5rNK/O3cKiq5ohtyiqq+eOMNZz5p0/5PH8Pd509iCmDu/Krt1YwfaWmsRGR0Gv3ZzAAfdMSj3nfPl0SGNUzmSVbi7n+pCwm9O385bqUhBhuO2MA972/mtlrC5k8MK3Z99tzoIJrn5tPRXUtXaIi+Pmby3lweh5Xj+9NRkocywqKWbJ1P2t3lVJT67hwVA9+ds4QunfqQHllNd/+23xuf3UxL988nuys1GNul4jI8bK2NJ9Wdna2y8nJCfpxP1ixg5fnb+Gpa8YQH/P1zK6oruHMP35KQkwU791+CpERjV/yKquo5tt/m8eaXaW8fPMERvdKZsHGIp6ds5GZq3fhHHSKi2ZEZidGZiZzxpCujO6V8rX3KCqr5NIn51JUVsnr359I/65JnrRZRNoGM8t1zmV78t4KGO+9s3Q7t726mCevHs05w9Mb3KaqppabX8jhs3WFPH1NNmcO7fa19duLD1JVU0uv1Phm+2W2FpVz8V/mUlZRTXpyB1LiY0iOi2Zg9yR+dOZAYqLa/ZVREfHzMmD0myYIzh2eTkZyHC/N29zgeuccP3tjOZ+uLeT+i4cfES4APZLj6N05odlwAeiZGs+r3x3PZWMyGdK9Ix2iI9hWfJAnZ61nWm7BcbdHRCQQ6oMJgsgI49vje/Hg9DXk7y494rLVnPw9TMst4LYz+nPluF4tcswB3ZK496JhX752znHxX+byxCf5XDYmU2cxIuI5/ZYJkivG9iQ60vjHvC1fW+6c4+EZa+nRqQO3nnFsI9kCYWbcceYAthUf5M3FoTmLmbt+Dw9Oz+OzdYVUVmuSUJG2TmcwQdIlMZZzh6fzem4Bd5096MvBALPWFLJkazH3Xzyc2KhIT2s4bWAaIzI78fgn+VwyOpPoyOD8fbH3QAX3vbeaN/zztj3xyXoSY6OYPLAL47JSKSqvYtu+gxTsK2f/wSpOH9yVK8f2pHfnhKDUJyLeUMAE0TUTevPWku28tWQ7V43rhXOOP85cS8/UOC7PzvT8+GbGHVMGcNMLOby5eBvfyu7p6fFqax3/yt3K/e/nUV5Zza2n9+emk/uQu3kfH+Xt4qPVu3l/+U7MoHvHDmQkx5GaEMNTn67nyVnrmdS/M1eO7cVpg9IavPmbiLRuCpggGtM7hcHdk3jpi81cObYnM1ftYvm2/fzhshFBO5s4Y3BXhmV05IlP8rnkxAyijuO4pYeqKDlUTUxkBLHREcRGRbBt30HmbShi3oa9zNuwl92lFYzLSuX+S4Z92fd05tBunDm0G7W1jt2lFXROjPla+3fuP8S/crbyz5yt3PbqYiIMhmd0YkLfzkzo25nJA9OaHO4tIq2DhikH2cvzN3PPmyuYdstEfvHWSg5WVvPhj089rl/0R2vGyp1MfSmXhy8fyaVjAj9zqql1rNi2n0/XFjJ7bSGLtxZTU9vwz0/XpFgm9uvMlCHdOH94OhHHEAi1tY4Fm4qYm7+HeRuKWLK1mMqaWq4a15PfXTLiqN9PRI6k78EEKBwCpqyimvH3f0RKQjRbiw7ypytGcvGJ3l8eq8s5x3mPzeFgVQ0zfzQ5oHA7VFXDxX+Zy+odJYDvjGLywC70So2nsrqWCv8jJT6GCX1T6dMlsCHVR+NQVQ2//yCP5z/fxPM3jOX0QV1b9P1F2iMvA8bTS2Rmlgw8AwwDHHCjc+6LOusNeBQ4FygHrnfOLfKvqwGW+zfd4py7wMtagyUhNopLR2fwwheb6ZeWwAUjM4Jew+ERZd97KZcXv9jMjQHcA+fxj/NZvaOE31x4AucNTz+q2xq0lA7Rkdx9zmA+z9/D3a8vY8adp9IpXn0zIq2V19dlHgU+cM4NBkYCq+utPwcY4H9MBZ6ss+6gc26U/9EmwuWwa0/KIi46krvOHhyyvoSzhnbj9EFp/GF6Hpv3ljW57bpdpTw1ez2Xjs7k2olZIQmXw2KjInno8pHsOVDJb95dFbI6RKR5ngWMmXUEJgPPAjjnKp1zxfU2uxB40fnMA5LNrOG5VNqQfmmJLP/1WXzzhO4hq8HMuP+S4URHRHDXtGXUNtKXUlvr+Pmby0mIjeKe84YEucqGjchM5gen9eP1RQVf3qZARFofLy+R9QUKgefNbCSQC9zhnKv753IGsLXO6wL/sh1ABzPLAaqBB5xz/27oIGY2Fd/ZD716tcy34IMhmJ36jUnvFMf/nD+E//f6cl6ev5lrJmYdsc2/creycNM+/nDpCFITYoJfZCNuO2MAM1ft4mdvLCc60li7q5RlBftZvm0/zkG/tAT6pSXSr2sinRNiqHWOqhpHTa0jJSGGSf06N/sZFJdX8taS7b5LcucMPqZZtxdt2cdv312FA+6YMoBTB6a1eN+USGvlWSe/mWUD84BJzrn5ZvYoUOKc+0Wdbd4Dfuecm+N//RFwl3Mu18x6OOe2m1lf4GNginNufVPHDIdO/tbGOce1zy0gd/M+pt85mZ6p8V+u23OggikPf8qg7kn8c+qEVveLceX2/Vz4+OdU+8++MpLjGJHZiajICNbvPsCGPQc4VNXwjAFpSbFccmIGl2dnfjl8uqqmlr0HKsnbWcK03AJmrNxFZU0tURFGr9R43vzhJDrFBdbns7+8it9Pz+PVBVvoltSBqEijYN9BxmWlctfZg8jOSqXkUBX5uw+Qv/sAHaIjj3m0ncjxCMtRZGbWHZjnnMvyvz4FuNs5d16dbZ4CZjnnXvW/XgOc5pzbUe+9/g6865yb1tQxFTDHZlvxQb75p9mMyOzEry84gf0Hqygur+KfC7fy6drd/OeOU1rttP8LNxVRVlHN8IxOR/QN1dY6thUfpLi8iqhIIzrSiIyIYN2uUv6VW8DHebupqXX0So3nQEU1RWWVX+6bHB/NRaN8AVRWUcPVz8xjYr8uPHdddqNnPmUV1azZVcriLcX85ZN8ig9WccNJWdz5jYHEREbwz4VbeOzjfApLK0hNiPna8QAm9E3lwctGfi3kRbwWlgEDYGafATc759aY2a+BBOfcT+usPw+4Fd8osvHAY865cWaWApQ75yrMrAvwBXChc67JXl0FzLE7/P2c+v77GwO5bcqAEFTkvcLSCv69eBuLtuwjNSGGtKRY0pJi6ZEcx0n9On9t6p7XFmzh7jeWc9PJffjF+UO/XL68YD/Pfb6RRVv2sXlv+ZfLT+yVzG8vGsYJPTp97ZgHK2t4ad4m8ncfoG9aIv3TEunfNZH5G/dy77urcc7xP+cP5cqxPVvdGaO0TeEcMKPwDVOOATYANwBXADjn/uofpvw4cDa+Yco3OOdyzOwk4CmgFt9AhEecc882dzwFzLFzzjFrTSEHKqpJjo8mOS6G1MQYMpLjQl1aq/Hrt1fy97mb+MOlI+iZGs9fZuXz2bo9JHWI4uT+XRiS3pHB3ZMYkt6RzJS4ow6Ign3l3DVtGXPX7+Xk/l24YVIWkwemBW2WB2mfwjZggk0BI16qrqnl+ucXMid/DwBdEmO46eS+XD2hFx1baK602lrHS/M28+hH6ygqq6RLYgwXjMzgsjGZDO3RsUWOIVKXAiZAChjx2v7yKn759gqye6dweXZPOkR7MwN2VU0ts9YU8npuAR/l7aKqxvHNE7px19mD6XcMo9lEGqOACZACRtqifWWVvDRvM099up5D1b652O6YMpC0pNB94VXaDt0yWaQdS0mI4fYpA/j0rtO5enwvXluwldMe/IRP8naHujSRJilgRMJEl8RYfnPhMGb8aDJ90hL43ku5zFqjkJHWSwEjEmb6piXyj5vG079rIlNfymX22sJQlyTSIAWMSBhKjo/h5ZvH0y8tke++mMOcdXtCXZLIERQwImEqJcEXMn26JHDTCwt5aPoaVu8ooS0N3JHwplFkImFu74EK/vtfS5m9tpBa/0Sf543owTUTemukmTRLw5QDpICR9mzPgQo+WLGT95btYP7GvaR3iuPFm8bpezPSJA1TFpFmdUmM5TsTevPq1An8+4eTOFRVw2VPzmXxln2hLk3aKQWMSBs0IjOZ179/Eh3jovn23+bzcZ5uzCbBp4ARaaOyuiQw7ZaT6Nc1ge++mMsTn+RzoKI61GVJO6I+GJE27kBFNT/+5xJmrNpFp7hobpiUxfUnZdEpLpqV20v4cPUuPly9i/iYKJ69LpukFpq4U8KDOvkDpIARadySrcU8/nE+H67eRUJMJB3jotmx/xBmMKpnMssL9jOmdwov3DjOs0k8pfVRwARIASPSvLydJTw9ewNlFdVMGdKNMwZ3pUtiLG8t2cad/1zClMFdefI7Y3QfmnbCy4CJ8uJNRaT1Gty9I3/81qgjll84KoOSg1X84q2V/L9py3jo8pFEROiumnLsFDAi8qVrJmZRXF7FwzPXEhcTyS//a+jXbh0tcjQUMCLyNbee0Z/Simqenr2B+RuLuO+iYYzv2znUZUkY0kVWEfkaM+Pn5w7h+evHcqiqhiuensdd05ayr6wy1KVJmFHAiEiDTh/clZk/OpVbTu3HG4u2cdYjs9lzoCLUZUkYUcCISKPiYiK5+5zBTPv+SRSVVfL4x/mhLknCiAJGRJo1qmcy38ruycvzN7Nlb3moy5EwoYARkYDceeYAIiOMh2asCXUpEiYUMCISkG4dO3DzyX15e+l2lhfsD3U5EgYUMCISsKmn9iUlPprff5AX6lIkDChgRCRgHTtEc9sZA5iTv4fZawtDXY60cgoYETkqV0/oRWZKHA/8J4/a2rYzl6G0PAWMiByV2KhIfvrNQazaUcJTszeEuhxpxRQwInLULhjZg/NGpPPQjDXM37A31OVIK6WAEZGjZmY8cMlweqXGc9uri/UNf2mQpwFjZslmNs3M8sxstZlNrLfezOwxM8s3s2VmNrrOuuvMbJ3/cZ2XdYrI0UvqEM1frh7N/oNV3PnaEmrUHyP1eH0G8yjwgXNuMDASWF1v/TnAAP9jKvAkgJmlAr8CxgPjgF+ZWYrHtYrIURqS3pF7LxzGnPw9/PnjdaEuR1oZzwLGzDoCk4FnAZxzlc654nqbXQi86HzmAclmlg58E5jpnCtyzu0DZgJne1WriBy7y7MzuXR0Jo9+tI6Zq3aFuhxpRbw8g+kLFALPm9liM3vGzBLqbZMBbK3zusC/rLHlRzCzqWaWY2Y5hYUaly8SbGbGvRedwPCMTtz6yiIWbioKdUnSSngZMFHAaOBJ59yJQBlwd71tGrofq2ti+ZELnXvaOZftnMtOS0s7nnpF5BjFx0Tx/PVjyUiO46a/LyRvZ0moS5JWwMuAKQAKnHPz/a+n4Quc+tv0rPM6E9jexHIRaaU6J8by4k3jiIuJ5LrnFrC1SLMut3eeBYxzbiew1cwG+RdNAVbV2+xt4Fr/aLIJwH7n3A5gOnCWmaX4O/fP8i8TkVYsMyWel24az6GqWq59bgFFugtmu+b1KLLbgJfNbBkwCrjfzG4xs1v8698HNgD5wN+AHwA454qAe4GF/sdv/MtEpJUb2C2J567PZmtROU/NXh/qciSEzLm2M3Y9Ozvb5eTkhLoMEQFufiGH5duKmXv3FCIjGupWldbAzHKdc9levLe+yS8inrhsTAa7Sir4bJ1Gd7ZXChgR8cQZg7uREh/NtNyCUJciIaKAERFPxERFcOGoDGas2sX+g1WhLkdCQAEjIp65dHQmldW1vLtM3zJojxQwIuKZYRkdGdQtSZfJ2ikFjIh4xsy4dEwGi7cUs77wQKjLkSBTwIiIpy4alUFkhPG6zmLaHQWMiHiqa8cOnDowjTcWbdM9Y9oZBYyIeO7S0ZnsLDnE5/l7Ql2KBJECRkQ8N2VIVzonxPDIh2t1FtOOKGBExHMdoiO557whLNpSzEtfbAp1ORIkChgRCYqLT8xg8sA0/jB9DduKD4a6HAkCBYyIBIWZcd9FwwC4583ltKWJdqVhAQWMmfUzs1j/89PM7HYzS/a2NBFpa3qmxvOTswYxa00hby3Rt/vbukDPYF4HasysP/As0Ad4xbOqRKTNuu6kLEb1TOZ/31nJ3gMVoS5HPBRowNQ656qBi4FHnHM/AtK9K0tE2qrICOP3l47gQEU197+fF+pyxEOBBkyVmV0FXAe8618W7U1JItLWDeqexI0n9+H1RQUsKygOdTnikUAD5gZgInCfc26jmfUB/uFdWSLS1t16en86J8Tw23dXq8O/jQooYJxzq5xztzvnXjWzFCDJOfeAx7WJSBuW1CGaH581kAWbipi+cmeoyxEPBDqKbJaZdTSzVGAp8LyZ/dHb0kSkrbsiuycDuyVy//t5VFTXhLocaWGBXiLr5JwrAS4BnnfOjQHO9K4sEWkPoiIj+J/zhrKlqJwX524OdTnSwgINmCgzSwe+xVed/CIix23ywDROG5TGYx+v07DlNibQgPkNMB1Y75xbaGZ9gXXelSUi7ck95w6hvLKGRz7Ur5W2JNBO/n8550Y4577vf73BOXept6WJSHsxoFsSV4/vxSsLtrB2V2moy5EWEmgnf6aZvWlmu81sl5m9bmaZXhcnIu3HnWcOJD4mknvfXaVhy21EoJfIngfeBnoAGcA7/mUiIi0iNSGGO6YM4LN1e5i1pjDU5UgLCDRg0pxzzzvnqv2PvwNpHtYlIu3QtROz6NMlgd++t4qqmtpQlyPHKdCA2WNm3zGzSP/jO8BeLwsTkfYnJiqCe84dwvrCMl6ep2HL4S7QgLkR3xDlncAO4DJ808eIiLSoKUO6cnL/Lvzpw3UUl1eGuhw5DoGOItvinLvAOZfmnOvqnLsI35cum2Rmm8xsuZktMbOcBtan+AcPLDOzBWY2LNB9RaRtMjP+5/whlB6q0rDlMHc8d7T8cYDbne6cG+Wcy25g3c+BJc65EcC1wKNHsa+ItFGDu3fk6vG9eeGLTczboKvx4ep4AsZa4PhDgY8AnHN5QJaZdWuB9xWRMHf3OYPJ6pzAj/65hP3lVaEuR47B8QRMIAPVHTDDzHLNbGoD65fiv9RmZuOA3kBmgPuKSBuWEBvFo1eOorC0gp+/uVzfjQlDTQaMmZWaWUkDj1J834lpziTn3GjgHOCHZja53voHgBQzWwLcBiwGqgPc93CNU80sx8xyCgs1dl6kLRmRmcx/nzWI95bv4F+5BaEuR46SBeuvAjP7NXDAOfdQI+sN2AiM8M/cHPC+h2VnZ7ucHI0HEGlLamsdVz8zn6UFxbx3+yn06ZIQ6pLaFDPL9aqf+3gukTXJzBLMLOnwc+AsYEW9bZLNLMb/8mZgtnOuJJB9RaR9iIgw/njFSKIjI7jztcXU1OpSWbjwLGCAbsAcM1sKLADec859YGa3mNkt/m2GACvNLA/fpbA7mtrXw1pFpBVL7xTHvRcNY2nBfl5dsCXU5UiAgnaJLBh0iUyk7XLOceXT81i7q5RPfnIayfExze8kzQrLS2QiIi3JzPj1BSew/2AVf5q5NtTlSAAUMCISNoak+76A+dK8zeTtLGl+BwkpBYyIhJUff2MgSR2i+d+3dd+Y1k4BIyJhJSUhhp+cNZAvNuzlPyt2hrocaYICRkTCzlXjejG4exL3vbda08i0YgoYEQk7UZER3HfxMApLK7jphYUcrKwJdUnSAAWMiISlMb1TeeTKUeRu2ccPXs7VHTBbIQWMiIStc4en89uLhvHJmkLumraMWn3Lv1WJCnUBIiLH4+rxvSk6UMnDM9eSEh/DL84fgm9qQwk1BYyIhL1bz+jP3rJKnvt8I5MHduG0QV1DXZKgS2Qi0gaYGT8/dwjdO3bg6dkbQl2O+ClgRKRNiImK4IZJWcxdv5cV2/aHuhxBASMibchV43uRGBvFUzqLaRUUMCLSZnTsEM23x/fi/eU72FpUHupy2j0FjIi0KdeflIUBz87ZGOpS2j0FjIi0KT2S47hgZA/+uXArxeWVoS6nXVPAiEib893JfTlYVcM/5m0OdSntmgJGRNqcIekdmTwwjb/P3cyhKs1TFioKGBFpk26Z3Jc9Byr4yyf5oS6l3VLAiEibNLFfZy4dncmfP8ln9trCUJfTLilgRKRNMjN+e9EwBnZN4o7XFrO9+GCoS2p3FDAi0mbFxUTyl++MprK6lltfWaQp/YNMASMibVq/tEQeuHQEi7YU88B/8kJdTruigBGRNu+/Rvbg2om9eXbORmat2R3qctoNBYyItAv3nDeEzJQ4Hv9Yo8qCRQEjIu1CbFQk15+URc7mfSzdWhzqctoFBYyItBtXjO1JYmyU5ikLEgWMiLQbSR2i+VZ2T95fvoMd+zVs2WsKGBFpV26YlEWtc7z4heYp85oCRkTalZ6p8Zw1tDuvzN9CeWV1qMs5bhv3lLF2VynOuVCXcgRPA8bMNpnZcjNbYmY5DaxPMbM3zWyZmS0ws2F11p1tZmvMLN/M7vayThFpX246pQ/7D1bx+qJtoS7luD316Xq+9dQXoS6jQcE4gzndOTfKOZfdwLqfA0uccyOAa4FHAcwsEngCOAcYClxlZkODUKuItAPZvVMYkdmJ5+dspLa29f3lfzRW7yhhSPeOmFmoSzlCqC+RDQU+AnDO5QFZZtYNGAfkO+c2OOcqgdeAC0NXpoi0JWbGTSf3YcOeMmatDd8vXlbX1JK3s5ShPTqGupQGeR0wDphhZrlmNrWB9UuBSwDMbBzQG8gEMoCtdbYr8C8TEWkR5w5Pp2tSLK/M3xLqUo7Zpr1lVFTXMiS9fQbMJOfcaHyXun5oZpPrrX8ASDGzJcBtwGKgGmjoXK/B81gzm2pmOWaWU1ioKblFJDDRkRFcMjqTT9YUUlhaEepyjsmqHaUADG2PAeOc2+7/727gTXyXvuquL3HO3eCcG4WvDyYN2IjvjKVnnU0zge2NHONp51y2cy47LS3Ng1aISFt12ZgMamod/14cnp39q7aXEB1p9O+aGOpSGuRZwJhZgpklHX4OnAWsqLdNspnF+F/eDMx2zpUAC4EBZtbHv/5K4G2vahWR9ql/1yRG9UxmWm5Bqxzm25zVO0ro3zWJmKhQd6c3zMuqugFzzGwpsAB4zzn3gZndYma3+LcZAqw0szx8l9HuAHDOVQO3AtOB1cD/OedWeliriLRTl43JZM2uUlZsKwl1KUdt9Y4ShqQnhbqMRkV59cbOuQ1oMdZGAAAQEElEQVTAyAaW/7XO8y+AAY3s/z7wvlf1iYiAbyr/37y7imm5Wxme2SnU5QRsz4EKdpdWtNr+Fwj9MGURkZDqFBfNN0/ozltLt1NRXRPqcgK2eofvjEsBIyLSil02JpPi8io+Wh0+34lZtd0XMK11iDIoYEREOLl/F7p37MC03IJQlxKw1TtKSO/UgZSEmOY3DhEFjIi0e5ERxiWjM5i1Zje7Sw6FupyArNpR0qrPXkABIyICwKVjMql18EYYfCfmUFUN6wvLWnX/CyhgREQA6JeWyJjeKfxfztZW/52Y/N0HqKl1OoMREQkXV47tyYbCMhZsLAp1KU36qoO/9X4HBhQwIiJfOm9EOkmxUby2cGvzG4fQqh0lxMdE0rtzQqhLaZICRkTELz4migtP7MF7y3dQXF4Z6nIatWpHCYO6JxEZ0fruAVOXAkZEpI6rxvWisrqWN1tpZ79zjtU7Slp9Bz8oYEREvuaEHp0YkdmJ1xa0zs7+bcUHKT1U3eo7+EEBIyJyhCvH9mLNrlIWby0OdSlHONzB31rvYlmXAkZEpJ4LRvUgPiaSV1vh3S5X7yjFDAZ3b90jyEABIyJyhMTYKC4Y2YN3l+2g9FBVqMv5mhXb95PVOYH4GM8mw28xChgRkQZcOa4XB6tqeGtJgzfTDYmqmlrmrd/L+D6poS4lIAoYEZEGjMzsxJD0jrz0xWZqa1tHZ//iLcWUVlRz6sDwuD28AkZEpAFmxtTJfVizq5QPV+8KdTkAfLp2N5ERxqQBXUJdSkAUMCIijfivET3olRrP45/kt4ohy7PWFDKmVwodO0SHupSAKGBERBoRFRnBD07rx7KC/cxetyektewuPcTK7SWcOig8Lo+BAkZEpEmXjM4kvVMH/vzRupCexcxe6wu4cOl/AQWMiEiTYqIiuOXUfuRs3sf8EM6y/OnaQrokxobFFDGHKWBERJpxxdiedEmM5fGP80Ny/Jpax2frCjl1YBoRrXyCy7oUMCIizegQHcn3JvdlTv4eFm3ZF/TjLy0opri8Kqz6X0ABIyISkG+P70VKfHRIzmJmrSkkwuCU/uExPPkwBYyISAASYqO4+ZS+fJy3m6VBngTz07WFjOyZTEpCTFCPe7wUMCIiAbrupCyS46N55MO1QTvm3gMVLCso5rSBXYN2zJaigBERCVBibBRTJ/flkzWFQeuLmZO/B+cIu/4XUMCIiByV6yZmkZoQwyMfrgvK8T5dU0hqQgwjMjoF5XgtSQEjInIUEmKj+N7kvsxeW0juZm+/F1NUVsn0lTs5fVDXsBqefJgCRkTkKF0zsTddEmP400xvz2Ke+WwD5VU13HJqX0+P4xVPA8bMNpnZcjNbYmY5DazvZGbvmNlSM1tpZjfUWVfj32+Jmb3tZZ0iIkcjPiaK703ux5z8PSzw6Nv9+8oqeWHuJs4bns6Abq3/7pUNCcYZzOnOuVHOuewG1v0QWOWcGwmcBjxsZofH4R307zfKOXdBEOoUEQnYdyb0pktiLA/PWOPJ/WKemeM7e7l9yoAWf+9gCfUlMgckmZkBiUARUB3akkREmhcXE8mdZw5g/sYiHvggr0Xfe19ZJX//fBPnDk9nYJievYD3AeOAGWaWa2ZTG1j/ODAE2A4sB+5wztX613Uwsxwzm2dmF3lcp4jIUbt6fC+um9ibp2dv4OnZ61vsfZ+ds9F39nJG+J69AER5/P6TnHPbzawrMNPM8pxzs+us/yawBDgD6Off5jPnXAnQy79vX+BjM1vunDviE/QH11SAXr16edwcEZGvmBm/+q8T2FNWyf3v59E5IZZLx2Qe13sWl1fy97mbOHdYOoO6h+/ZC3h8BuOc2+7/727gTWBcvU1uAN5wPvnARmBwvX03ALOAExs5xtPOuWznXHZaWvh9EUlEwltEhPHHb41kUv/O3PX6Mj7OO77bKz87ZyMHKqrDuu/lMM8CxswSzCzp8HPgLGBFvc22AFP823QDBgEbzCzFzGL9y7sAk4BVXtUqInI8YqMi+et3xjAkPYkfvLyIldv3H9P75O8u5dk5Gzl3ePewP3sBb89gugFzzGwpsAB4zzn3gZndYma3+Le5FzjJzJYDHwH/zzm3B1+/TI5/30+AB5xzChgRabWSOkTz3PVj6RQXzff/sYj95VVHtX95ZTXf/8ci4qIj+eX5J3hUZXBZKG8B2tKys7NdTs4RX7cREQma3M1FXPHUPE4dmMbfrs0O6Bv4zjn++/+W8uaSbbx043hOHhC8afnNLLeRr5Ect1APUxYRaVPG9E7lF+cP5aO83TzxSWD3jnlt4VbeWLyNO6cMDGq4eE0BIyLSwq6d2JuLRvXgjx+uZfbawia3XbFtP796eyWnDOjCbWf0D1KFwaGAERFpYWbG/ZcMZ2DXJG5/bTH/XryN6prar21TW+t4f/kOvvdSLqnxMTxyxaiwnNCyKQoYEREPxMdE8dQ1Y+iaFMud/1zCqQ/O4oW5myg9VMWbiws465HZ/ODlRcRGRfDUNWPonBgb6pJbnDr5RUQ8VFvr+DhvN09+up7czfuIMKh1MLh7Ej88vT/nDk8nMoRnLl528nv9TX4RkXYtIsI4c2g3zhzajYWbinhn6XZOGZDGlMHheY+Xo6GAEREJkrFZqYzNSg11GUGjPhgREfGEAkZERDyhgBEREU8oYERExBMKGBER8YQCRkREPKGAERERTyhgRETEE21qqhgzKwQ211vcCah/e7n6y+q+bu55F2DPcZTZUD2BbnO0ban/+vDzttSWus+Ppz3H05bG1unn7Ktl+mwCq7W5bbz4bAY557y5faZzrk0/gKebW1b3dXPPgZyWrifQbY62LU20oc20paXaczxt0c9Z0z9n+mza7mfT3KM9XCJ7J4Bl7xzl85auJ9BtjrYt9V+/08g2x6o1tCXQOppzPG1pbJ1+zlqGPpuml4fys2lSm7pEFgxmluM8mnk02NpSW6BttacttQXaVnvaUlvA2/a0hzOYlvZ0qAtoQW2pLdC22tOW2gJtqz1tqS3gYXt0BiMiIp7QGYyIiHiiXQeMmT1nZrvNbMUx7DvGzJabWb6ZPWZmVmfdbWa2xsxWmtkfWrbqRutp8baY2a/NbJuZLfE/zm35yhutyZPPxr/+J2bmzKxLy1XcZD1efDb3mtky/+cyw8x6tHzlDdbjRVseNLM8f3veNLPklq+80Zq8aM/l/n/7tWbmeV/N8bShkfe7zszW+R/X1Vne5L+rBnk1PC0cHsBkYDSw4hj2XQBMBAz4D3COf/npwIdArP911zBuy6+Bn7SVz8a/ricwHd/3pbqEa1uAjnW2uR34axi35Swgyv/898Dvw/nnDBgCDAJmAdmttQ3++rLqLUsFNvj/m+J/ntJUe5t6tOszGOfcbKCo7jIz62dmH5hZrpl9ZmaD6+9nZun4/oF/4Xz/518ELvKv/j7wgHOuwn+M3d62wsejtoSMh+35E3AXELTORy/a4pwrqbNpAkFqj0dtmeGcq/ZvOg/I9LYVX/GoPaudc2uCUb//eMfUhkZ8E5jpnCtyzu0DZgJnH+vviXYdMI14GrjNOTcG+Anwlwa2yQAK6rwu8C8DGAicYmbzzexTMxvrabVNO962ANzqv3TxnJmleFdqQI6rPWZ2AbDNObfU60IDcNyfjZndZ2ZbgauBX3pYa3Na4ufssBvx/XUcSi3ZnlAJpA0NyQC21nl9uF3H1N6oAA/aLphZInAS8K86lxdjG9q0gWWH/4KMwndqOQEYC/yfmfX1p37QtFBbngTu9b++F3gY3y+AoDve9phZPHAPvssxIdVCnw3OuXuAe8zsZ8CtwK9auNRmtVRb/O91D1ANvNySNR6NlmxPqDTVBjO7AbjDv6w/8L6ZVQIbnXMX03i7jqm9CpiviwCKnXOj6i40s0gg1//ybXy/eOuexmcC2/3PC4A3/IGywMxq8c1dVOhl4Q047rY453bV2e9vwLteFtyM421PP6APsNT/jy4TWGRm45xzOz2uvb6W+Dmr6xXgPUIQMLRQW/ydyecDU4L9x1g9Lf3ZhEKDbQBwzj0PPA9gZrOA651zm+psUgCcVud1Jr6+mgKOpb1ed0C19geQRZ3OMWAucLn/uQEjG9lvIb6zlMMdXuf6l98C/Mb/fCC+000L07ak19nmR8Br4fzZ1NtmE0Hq5PfosxlQZ5vbgGlh3JazgVVAWjB/vrz+OSNInfzH2gYa7+TfiO8qTIr/eWog7W2wrlB8oK3lAbwK7ACq8CX0Tfj+yv0AWOr/of9lI/tmAyuA9cDjfPWl1RjgH/51i4AzwrgtLwHLgWX4/mpLD0ZbvGpPvW02EbxRZF58Nq/7ly/DN69URhi3JR/fH2JL/I+gjIjzsD0X+9+rAtgFTG+NbaCBgPEvv9H/meQDNzTX3qYe+ia/iIh4QqPIRETEEwoYERHxhAJGREQ8oYARERFPKGBERMQTChhp08zsQJCP94yZDW2h96ox32zJK8zsneZmGTazZDP7QUscW6QlaJiytGlmdsA5l9iC7xflvpqY0VN1azezF4C1zrn7mtg+C3jXOTcsGPWJNEdnMNLumFmamb1uZgv9j0n+5ePMbK6ZLfb/d5B/+fVm9i8zeweYYWanmdksM5tmvvuYvHz43hj+5dn+5wf8E1IuNbN5ZtbNv7yf//VCM/tNgGdZX/DVpJ2JZvaRmS0y3/05LvRv8wDQz3/W86B/25/6j7PMzP63Bf83ijRLASPt0aPAn5xzY4FLgWf8y/OAyc65E/HNTnx/nX0mAtc5587wvz4RuBMYCvQFJjVwnARgnnNuJDAb+G6d4z/qP36z8zn558Gagm82BYBDwMXOudH47j/0sD/g7gbWO+dGOed+amZnAQOAccAoYIyZTW7ueCItRZNdSnt0JjC0zkyzHc0sCegEvGBmA/DNFBtdZ5+Zzrm699xY4JwrADCzJfjmgppT7ziVfDVBaC7wDf/ziXx1L41XgIcaqTOuznvn4rs3B/jmgrrfHxa1+M5sujWw/1n+x2L/60R8gTO7keOJtCgFjLRHEcBE59zBugvN7M/AJ865i/39GbPqrC6r9x4VdZ7X0PC/pSr3VSdnY9s05aBzbpSZdcIXVD8EHsN3/5c0YIxzrsrMNgEdGtjfgN855546yuOKtAhdIpP2aAa++6cAYGaHpzXvBGzzP7/ew+PPw3dpDuDK5jZ2zu3Hd1vkn5hZNL46d/vD5XSgt3/TUiCpzq7TgRv99wfBzDLMrGsLtUGkWQoYaevizaygzuPH+H5ZZ/s7vlfhu8UCwB+A35nZ50CkhzXdCfzYzBYA6cD+5nZwzi3GNzPulfhuyJVtZjn4zmby/NvsBT73D2t+0Dk3A98luC/MbDkwja8HkIinNExZJMj8d9c86JxzZnYlcJVz7sLm9hMJN+qDEQm+McDj/pFfxYToNtQiXtMZjIiIeEJ9MCIi4gkFjIiIeEIBIyIinlDAiIiIJxQwIiLiCQWMiIh44v8DfLQhlklJkrYAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "learn.recorder.plot(skip_end=15)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "Total time: 21:51 <p><table style='width:300px; margin-bottom:10px'>\n",
       "  <tr>\n",
       "    <th>epoch</th>\n",
       "    <th>train_loss</th>\n",
       "    <th>valid_loss</th>\n",
       "    <th>accuracy</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>1</th>\n",
       "    <th>4.294265</th>\n",
       "    <th>4.150173</th>\n",
       "    <th>0.285341</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "\n",
       "  </tr>\n",
       "</table>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "learn.fit_one_cycle(1, 1e-2, moms=(0.8,0.7))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn.save('fit_head')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn.load('fit_head');"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To complete the fine-tuning, we can then unfeeze and launch a new training."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn.unfreeze()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "Total time: 7:55:12 <p><table style='width:300px; margin-bottom:10px'>\n",
       "  <tr>\n",
       "    <th>epoch</th>\n",
       "    <th>train_loss</th>\n",
       "    <th>valid_loss</th>\n",
       "    <th>accuracy</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>1</th>\n",
       "    <th>4.206899</th>\n",
       "    <th>4.139874</th>\n",
       "    <th>0.286488</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>2</th>\n",
       "    <th>4.193705</th>\n",
       "    <th>4.126574</th>\n",
       "    <th>0.287702</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>3</th>\n",
       "    <th>4.207431</th>\n",
       "    <th>4.111065</th>\n",
       "    <th>0.289151</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>4</th>\n",
       "    <th>4.199276</th>\n",
       "    <th>4.096888</th>\n",
       "    <th>0.290250</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>5</th>\n",
       "    <th>4.177352</th>\n",
       "    <th>4.084046</th>\n",
       "    <th>0.291225</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>6</th>\n",
       "    <th>4.178374</th>\n",
       "    <th>4.074270</th>\n",
       "    <th>0.291789</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>7</th>\n",
       "    <th>4.186607</th>\n",
       "    <th>4.066679</th>\n",
       "    <th>0.292630</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>8</th>\n",
       "    <th>4.190486</th>\n",
       "    <th>4.060092</th>\n",
       "    <th>0.293026</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>9</th>\n",
       "    <th>4.145438</th>\n",
       "    <th>4.054630</th>\n",
       "    <th>0.293494</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>10</th>\n",
       "    <th>4.126917</th>\n",
       "    <th>4.051110</th>\n",
       "    <th>0.293746</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>11</th>\n",
       "    <th>4.149212</th>\n",
       "    <th>4.047611</th>\n",
       "    <th>0.294092</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>12</th>\n",
       "    <th>4.123378</th>\n",
       "    <th>4.044738</th>\n",
       "    <th>0.294507</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>13</th>\n",
       "    <th>4.109120</th>\n",
       "    <th>4.042897</th>\n",
       "    <th>0.294769</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>14</th>\n",
       "    <th>4.138960</th>\n",
       "    <th>4.040787</th>\n",
       "    <th>0.295025</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>15</th>\n",
       "    <th>4.117061</th>\n",
       "    <th>4.039592</th>\n",
       "    <th>0.295129</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>16</th>\n",
       "    <th>4.119782</th>\n",
       "    <th>4.037540</th>\n",
       "    <th>0.295335</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>17</th>\n",
       "    <th>4.120603</th>\n",
       "    <th>4.037851</th>\n",
       "    <th>0.295442</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>18</th>\n",
       "    <th>4.111146</th>\n",
       "    <th>4.036582</th>\n",
       "    <th>0.295570</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>19</th>\n",
       "    <th>4.075064</th>\n",
       "    <th>4.036627</th>\n",
       "    <th>0.295581</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>20</th>\n",
       "    <th>4.068545</th>\n",
       "    <th>4.036455</th>\n",
       "    <th>0.295598</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "\n",
       "  </tr>\n",
       "</table>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "learn.fit_one_cycle(20, 1e-3, moms=(0.8,0.7))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn.save('fine_tuned')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "How good is our model? Well let's try to see what it predicts after a few given words."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn.load('fine_tuned');"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "TEXT = \"i liked this movie because\"\n",
    "N_WORDS = 40\n",
    "N_SENTENCES = 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "Total time: 00:03 <p>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "Total time: 00:02 <p>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "i liked this movie because of the best of all the stealer , nun , hatred is much like a crash jump ahead of this however , the opening . xxmaj british xxmaj crap outta 10 minute or even where a while the following the\n",
      "i liked this movie because xxmaj brotherly ) . xxmaj maintain pleaser of dire the comprised of the virus is viewers uneasy ' little xxmaj silver - hope to classified for this hunt shaped into being described tank 1955 on xxmaj firefly through four out\n"
     ]
    }
   ],
   "source": [
    "print(\"\\n\".join(learn.predict(TEXT, N_WORDS) for _ in range(N_SENTENCES)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We have to save the model but also it's encoder, the part that's responsible for creating and updating the hidden state. For the next part, we don't care about the part that tries to guess the next word."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn.save_encoder('fine_tuned_enc')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Classifier"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, we'll create a new data object that only grabs the labelled data and keeps those labels. Again, this line takes a bit of time."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "path = untar_data(URLs.IMDB)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "data_clas = (TextList.from_folder(path, vocab=data_lm.vocab)\n",
    "             #grab all the text files in path\n",
    "             .split_by_folder(valid='test')\n",
    "             #split by train and valid folder (that only keeps 'train' and 'test' so no need to filter)\n",
    "             .label_from_folder(classes=['neg', 'pos'])\n",
    "             #label them all with their folders\n",
    "             .databunch(bs=bs))\n",
    "\n",
    "data_clas.save('tmp_clas')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "data_clas = TextClasDataBunch.load(path, 'tmp_clas', bs=bs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table>  <col width='90%'>  <col width='10%'>  <tr>\n",
       "    <th>text</th>\n",
       "    <th>target</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>xxbos xxmaj match 1 : xxmaj tag xxmaj team xxmaj table xxmaj match xxmaj bubba xxmaj ray and xxmaj spike xxmaj dudley vs xxmaj eddie xxmaj guerrero and xxmaj chris xxmaj benoit xxmaj bubba xxmaj ray and xxmaj spike xxmaj dudley started things off with a xxmaj tag xxmaj team xxmaj table xxmaj match against xxmaj eddie xxmaj guerrero and xxmaj chris xxmaj benoit . xxmaj according to the rules</th>\n",
       "    <th>pos</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>xxbos xxmaj some have praised xxunk :- xxmaj the xxmaj lost xxmaj xxunk as a xxmaj disney adventure for adults . i do n't think so -- at least not for thinking adults . \\n\\n xxmaj this script suggests a beginning as a live - action movie , that struck someone as the type of crap you can not sell to adults anymore . xxmaj the \" crack staff \"</th>\n",
       "    <th>neg</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>xxbos xxunk ) is the developing world 's answer to xxmaj silence of the xxmaj lambs . xxmaj where ` xxmaj silence ' terrorized our peace of mind , ` xxmaj citizen ' exhausts and saddens us instead . xxmaj this dramatization of the xxmaj chikatilo case translates rather well , thanks to a xxmaj westernized friendship between two xxmaj rostov cops who become equals . \\n\\n citizenx may also</th>\n",
       "    <th>pos</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>xxbos 8 xxmaj simple xxmaj rules for xxmaj dating xxmaj my xxmaj teenage xxmaj daughter had an auspicious start . xxmaj the supremely - talented xxmaj tom xxmaj shadyac was involved in the project . xxmaj this meant that the comedy would be nothing less of spectacular , and that 's exactly what happened : the show remains one of the freshest , funniest , wittiest shows made in a</th>\n",
       "    <th>pos</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>xxbos xxmaj the vigilante has long held a fascination for audiences , inasmuch as it evokes a sense of swift , sure justice ; good triumphs over evil and the bad guy gets his deserts . xxmaj it is , in fact , one of the things that has made the character of xxmaj dirty xxmaj harry xxmaj callahan ( as played by xxmaj clint xxmaj eastwood ) so popular</th>\n",
       "    <th>pos</th>\n",
       "  </tr>\n",
       "</table>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "data_clas.show_batch()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can then create a model to classify those reviews and load the encoder we saved before."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn = text_classifier_learner(data_clas, drop_mult=0.5)\n",
    "learn.load_encoder('fine_tuned_enc')\n",
    "learn.freeze()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "gc.collect();"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.\n"
     ]
    }
   ],
   "source": [
    "learn.lr_find()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "learn.recorder.plot()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Total time: 02:46\n",
      "epoch  train_loss  valid_loss  accuracy\n",
      "1      0.294225    0.210385    0.918960  (02:46)\n",
      "\n"
     ]
    }
   ],
   "source": [
    "learn.fit_one_cycle(1, 2e-2, moms=(0.8,0.7))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "Total time: 04:03 <p><table style='width:300px; margin-bottom:10px'>\n",
       "  <tr>\n",
       "    <th>epoch</th>\n",
       "    <th>train_loss</th>\n",
       "    <th>valid_loss</th>\n",
       "    <th>accuracy</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "    <th>1</th>\n",
       "    <th>0.507567</th>\n",
       "    <th>0.344481</th>\n",
       "    <th>0.855000</th>\n",
       "  </tr>\n",
       "  <tr>\n",
       "\n",
       "  </tr>\n",
       "</table>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "learn.fit_one_cycle(1, 2e-2, moms=(0.8,0.7))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn.save('first')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn.load('first');"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Total time: 03:03\n",
      "epoch  train_loss  valid_loss  accuracy\n",
      "1      0.268781    0.180993    0.930760  (03:03)\n",
      "\n"
     ]
    }
   ],
   "source": [
    "learn.freeze_to(-2)\n",
    "learn.fit_one_cycle(1, slice(1e-2/(2.6**4),1e-2), moms=(0.8,0.7))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn.save('second')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn.load('second');"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Total time: 04:06\n",
      "epoch  train_loss  valid_loss  accuracy\n",
      "1      0.211133    0.161494    0.941280  (04:06)\n",
      "\n"
     ]
    }
   ],
   "source": [
    "learn.freeze_to(-3)\n",
    "learn.fit_one_cycle(1, slice(5e-3/(2.6**4),5e-3), moms=(0.8,0.7))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn.save('third')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn.load('third');"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Total time: 10:01\n",
      "epoch  train_loss  valid_loss  accuracy\n",
      "1      0.188145    0.155038    0.942480  (05:00)\n",
      "2      0.159475    0.153531    0.944040  (05:01)\n",
      "\n"
     ]
    }
   ],
   "source": [
    "learn.unfreeze()\n",
    "learn.fit_one_cycle(2, slice(1e-3/(2.6**4),1e-3), moms=(0.8,0.7))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('pos', tensor(0), tensor([[9.9999e-01, 1.1991e-05]]))"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "learn.predict(\"I really loved that movie, it was awesome!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
